<?php
namespace Common\ORG;

/**
* 企业号接口
* 
* @package ORG
* @author Zhangye<zhagye@hzhfzx.com>
* @date  06/15/2017
* 
*  == 调用示范 ==
* $MQy =  new Common\ORG\Qy(' 企业号缩写');
* $MQy->createUser(参数 )
*
*  == 接口类型 ==
*  Department => 通讯录部门管理
*  Tag => 标签管理
*  User => 订阅用户管理
*  App  => 栏目应用
*
*/

use Admin\Model;

class Qy {
    const TOKEN_CACHE_KEY = 'qy_token';
    const QY_CONFIG_KEY = 'QYH';
    const QY_URL_TOKEN = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken';
    protected $m_token = '';
    protected $m_config = array();

    /**
     * 初始化函数
     * 
     * @param string $qyCode 企业号编号
    */
    public function __construct( $qyCode = '')
    {
        $qyConf = C( self::QY_CONFIG_KEY );
        if ($qyCode){
            if ($qyConf&&is_array($qyConf)&&isset($qyConf[$qyCode]))
                $this->m_config = $qyConf[$qyCode];
            $this->m_token = $this->token();
        }
    }


    public function token( $update = false)
    {
        if (count($this->m_config)&&isset($this->m_config['corpCode'])){
            $tokenCache = F(self::TOKEN_CACHE_KEY);
            if (!$tokenCache)
                $tokenCache = array();
            $tm = time();
            $dataKey =  $this->m_config&&isset($this->m_config['corpCode']) ? $this->m_config['corpCode']:'';
            if ($dataKey){
                $data = isset($tokenCache[$dataKey]) ? $tokenCache[$dataKey]:'';
                if ($data&&$data['time']>$tm && !$update){
                    return $data['token'];
                }
                //更新token数据
                $tokenData = array('corpid'=>'','corpsecret'=>'');
                $tokenData['corpid'] = isset($this->m_config['corpId']) ? $this->m_config['corpId'] : '';
                $tokenData['corpsecret'] = isset($this->m_config['corpSecret']) ? $this->m_config['corpSecret'] : '';
                $httpUrl = self::QY_URL_TOKEN.'?'.http_build_query($tokenData);
                $httpData = \Common\ORG\Tools\Http::get($httpUrl);
                if ($httpData&&json_decode($httpData)){
                    $httpRes = json_decode($httpData, true);
                    if ($httpRes&&isset($httpRes['access_token'])){
                        $tokenCache[$dataKey] = array('time'=>time(), 'token'=>'');
                        $tokenCache[$dataKey]['time'] += intval($httpRes['expires_in']);
                        $tokenCache[$dataKey]['token'] = $httpRes['access_token'];
                        F(self::TOKEN_CACHE_KEY, $tokenCache);
                        return  $tokenCache[$dataKey]['token'];
                    }
                }
            }
        }

        return '';
    }

    /**
     * 接口不存在 
     * 
    */
    public function apiError()
    {
        $res = array('rcode'=>0, 'msg'=> '接口调用错误');
        return $res;
    }

    /**
     * 根据接口名匹配要调用的企业号接口
     * 
    */
    private function _parseApi( $name )
    {
        $res = array('rcode'=>0, 'class'=>'','method'=>'');
        if ($name && preg_match('#[A-Z]#',$name)){
            $parts = array();
            $len = 0;
            for($i=0;$i<strlen($name);$i++){
                if (preg_match('#[A-Z]#', substr($name,$i,1)))
                    $len++;
                if (!isset($parts[$len]))
                    $parts[$len] = '';
                $parts[$len] .= substr($name,$i,1);
            }
            $len = count($parts);
            $p0 = array_slice($parts,0, $len-1);
            $p1 = array_slice($parts,$len-1);
            $class = $p1[0];
            $method = implode('', $p0 );
            $res['rcode'] = 1;
            $res['class'] = $class;
            $res['method'] = $method ;
        }
        return $res;
    }

    /**
     * 企业号接口调用魔术方法
     * 
    */
    public function __call($name, $arg)
    {
        $apiData = $this->_parseApi( $name );
        if ($apiData['rcode']){
            $path = dirname(__FILE__).'/Qy/'.$apiData['class'].'.class.php';
            if (file_exists($path)){
                $className = "\\Common\\ORG\\Qy\\".$apiData['class'];
                $methodName = $apiData['method'];
                $token = $this->token();
                $class = new $className( $token );
                if (method_exists($class, $methodName)){
                    return call_user_func_array(array($class, $methodName), $arg);
                }
            }
        }
        return $this->apiError();
    }

}

?>